module trigger(

/*--------------------------------触发所需的信号--------------------------------*/
	input		[11:0]	DataIn_CH,		//外部信号输入(转换后数据)
	input				Trigger_CH,		//触发通道选中：0选空，1选中
	input		[1:0]	TriggerMode,	//边沿触发选择：01为上升沿，10为下降沿
	input		[12:0]	TriggerLV,		//触发电平设置
	input		[13:0]	TriggerRange,	//预存储深度，0~100%，总计16k
	input		[13:0]	SamplDivinum,	//采样率衰减倍数X：X=0为50M，X≠0为50M/X
	input				VerusTrigger,	//底板发出的触发信号，接收信号后开始将数据存入FIFO

	input				TriggerST,		//底板发出的允许触发信号
	output				TriggerSignal,	//产生的触发信号，该信号产生后关闭触发功能
	output	reg			TriggerRange_gt,//预存储数据存满标志

    input   			clk50M,			//ADC返回时钟，50MTriggerSignal
    input   			rst_n,			//上电复位信号
    // input   			enFIFORst,		//FIFO清零
    input   			rd_CH,			//上位机取数的门时钟
	input				wr_fifo,		//经过衰减后的实际采样时钟


    output  	[11:0]	DataOut_CH		//传输给上位机的数据

);

/*--------------------------------采样率控制--------------------------------*/
// reg wr_fifo;//FIFO写时钟 实际采样率
// reg [13:0] SamplDivinum_tp;
// always@(posedge clk50M or negedge rst_n) begin
// 	if (!rst_n) begin
// 		wr_fifo	<= 1'b0;
// 		SamplDivinum_tp	<= 14'h1;
// 	end else begin
// 		if (|SamplDivinum == 1'b1) begin
// 			if(SamplDivinum_tp == SamplDivinum) begin
// 				wr_fifo	<= 1'b1;
// 				SamplDivinum_tp	<= 14'h1;
// 			end else begin
// 				wr_fifo	<= 1'b0;
// 				SamplDivinum_tp	<= SamplDivinum_tp + 1'b1;
// 			end
// 		end else begin
// 			wr_fifo	<=	clk50M;
// 		end
// 	end
// end

/**/
// /*--------------------------------采样率控制--------------------------------*/
// wire wr_fifo;//FIFO写时钟 实际采样率
// assign wr_fifo = |SamplDivinum ? clkfisp : clk50M;//SamplDivinum全0 采样率为50M

// reg clkfisp;
// reg[13:0] divict;
// always@(posedge clk50M)
// begin
// 	if(!rst_n)
// 	begin
// 		clkfisp	<= 1'b0;
// 		divict	<= 14'h1;
// 	end
// 	else
// 	begin
// 		if(divict == SamplDivinum)
// 		begin
// 			clkfisp	<= 1'b1;
// 			divict	<= 14'h1;
// 		end
// 		else
// 		begin
// 			clkfisp	<= 1'b0;
// 			divict	<= divict + 1'b1;
// 		end
// 	end
// end
// /**/

/*--------------------------------预存储设置--------------------------------*/
//控制FIFO的读时钟，在所有通道预置数据存满前禁用触发功能，触发之前将读时钟与写时钟同步
wire rd_fifo;//FIFO读时钟
reg rd_switch;
reg [13:0] TriggerRange_tp;
// reg TriggerRange_gt;//预置数据存满标志
assign rd_fifo = rd_switch ? wr_fifo : (!rd_CH);
always@(posedge wr_fifo or negedge rst_n) begin
	if (!rst_n) begin
		rd_switch	<= 1'b0;
		TriggerRange_tp	<= 14'h0;
		TriggerRange_gt	<= 1'b0;
	end else begin
		if (vtrig) begin
			rd_switch	<= 1'b0;
			TriggerRange_gt	<= 1'b1;
		end else begin
			if (TriggerRange_tp == TriggerRange) begin
				rd_switch	<= 1'b1;
				TriggerRange_gt	<= 1'b1;
			end else begin
				rd_switch	<= 1'b0;
				TriggerRange_tp	<= TriggerRange_tp + 1'b1;
			end
		end
	end
end

reg VerusTrigger_aft,VerusTrigger_pre,vtrig;
always @(posedge clk50M or negedge rst_n) begin
	if (!rst_n) begin
		VerusTrigger_aft	<= 1'b0;
		VerusTrigger_pre	<= 1'b0;
		vtrig				<= 1'b0;
	end else begin
		VerusTrigger_aft	<= VerusTrigger;
		VerusTrigger_pre	<= VerusTrigger_aft;
		if ((!VerusTrigger_pre) && VerusTrigger_aft) begin
			vtrig	<= 1'b1;
		end else begin
			vtrig	<= vtrig;
		end
	end
end

reg[13:0] cnt_tri/*synthesis noprune*/;
always @(posedge wr_fifo or negedge rst_n) begin
	if (!rst_n) begin
		cnt_tri	<= 14'h0;
	end else begin
		if (VerusTrigger == 1'b1) begin
			if (wrfull == 1'b0) begin
				cnt_tri	<= cnt_tri + 1'b1;
			end else begin
				cnt_tri	<= cnt_tri;
			end
		end else begin
			cnt_tri	<= 14'h0;
		end
	end
end

reg VerusTTrigger/*synthesis noprune*/;
reg VerusTrigger1/*synthesis noprune*/;
reg VerusTrigger2/*synthesis noprune*/;
// always @(posedge clk50M or negedge rst_n) begin
// 	if (!rst_n) begin
// 		VerusTTrigger	<= 1'b0;
// 	end else begin
// 		VerusTrigger1	<= VerusTrigger;
// 		VerusTrigger2	<= VerusTrigger1;
// 		if (!VerusTrigger2 && VerusTrigger1) begin
// 			VerusTTrigger	<= 1'b1;
// 		end else begin
// 			VerusTTrigger	<= VerusTTrigger;
// 		end
// 	end
// end

/**/
wire wrfull;
wire[11:0] data_in_ch;
wire[11:0] Data_CH;
assign	data_in_ch = (cnt_tri >= 14'd100) ? 12'h100 : DataIn_CH;
FIFO24 U1(
	.aclr(!rst_n),

	.data(Data_CH),
	.wrclk(wr_fifo),
	.wrreq(1'b1),

	.rdclk(rd_fifo),
	.rdreq(1'b1),
	.q(DataOut_CH),

	.rdempty(),
	.wrusedw(),
	.wrfull(wrfull)
);

wire[11:0] Data1_CH;
FIFO12 U2(
	.aclr(!rst_n),
	.data(DataIn_CH),
	.wrclk(wr_fifo),
	.wrreq(1'b1),
	.rdclk(wr_fifo),
	.rdreq(1'b1),
	.q(Data_CH)
);

// /*--------------------------------预存储设置--------------------------------*/
// wire clkout;//FIFO读时钟
// reg prest;
// reg[14:0] presto;
// assign clkout = (presw ? 1'b1 : prest) ? rd_CH : wr_fifo;
// always@(posedge wr_fifo)
// begin
// 	if(!enFIFORst)
// 	begin
// 		prest	<= 1'b0;
// 		presto	<= 15'h0;
// 	end
// 	else
// 	begin
// 		if(presto == prestoset)
// 		begin
// 			prest	<= 1'b0;
// 		end
// 		else
// 		begin
// 			prest	<= 1'b1;
// 			presto	<= presto + 1'b1;
// 		end
// 	end
// end
// /**/

/*--------------------------------触发控制--------------------------------*/
reg[12:0] DataIn_Comp;
always @(posedge clk50M or negedge rst_n) begin
	if (!rst_n) begin
		DataIn_Comp	<= 13'h0;
	end else begin
		if (DataIn_CH[11] == 1'b0) begin
			DataIn_Comp	<= ((DataIn_CH + 13'h1000) >> 3'h2);
		end else begin
			DataIn_Comp	<= (DataIn_CH >> 3'h2);
		end
	end
end


//选择上升沿还是下降沿触发
assign TriggerSignal =	(TriggerMode == 2'b01) ? trigPos :
						(TriggerMode == 2'b10) ? trigNeg : 1'b0;
//上升沿触发
reg trigPos;
reg sigPos;
reg trigGtPos;
reg[3:0] cnt1;
always @(posedge wr_fifo or negedge rst_n) begin
	if (!rst_n) begin
		trigPos		<= 1'b0;
		sigPos		<= 1'b0;
		cnt1		<= 4'h0;
		trigGtPos	<= 1'b0;
	end else begin
		if ((DataIn_Comp < (TriggerLV >> 3'h2)) && (sigPos == 1'b0) && (TriggerMode == 2'b01) && (trigGtPos == 1'b0) && (Trigger_CH == 1'b1) && (TriggerST == 1'b1)) begin
			sigPos	<= 1'b1;
			cnt1	<= 4'h0;
		end else if ((sigPos == 1'b1) && (cnt1 < 4'h8)) begin
			cnt1	<= cnt1 + 1'b1;
		end else if (cnt1 == 4'h8) begin
			if (DataIn_Comp > (TriggerLV >> 3'h2)) begin
				trigPos		<= 1'b1;
				trigGtPos	<= 1'b1;
				sigPos		<= 1'b0;
				cnt1		<= 4'h0;
			end else begin
				trigPos		<= 1'b0;
				sigPos		<= 1'b0;
				cnt1		<= 4'h0;
			end
		end else begin
			trigPos	<= trigPos;
		end
	end
end

// reg aa/*synthesis noprune*/;
// always @(posedge wr_fifo or negedge rst_n) begin
// 	if (!rst_n) begin
// 		aa	<= 1'b0;
// 	end else begin
// 		if (DataIn_Comp < (TriggerLV >> 3'h2)) begin
// 			aa	<= 1'b1;
// 		end else begin
// 			aa	<= 1'b0;
// 		end
// 	end
// end

//下降沿触发
reg trigNeg;
reg sigNeg;
reg trigGtNeg;
reg[3:0] cnt2;
always @(posedge wr_fifo or negedge rst_n) begin
	if (!rst_n) begin
		trigNeg		<= 1'b0;
		sigNeg		<= 1'b0;
		cnt2		<= 4'h0;
		trigGtNeg	<= 1'b0;
	end else begin
		if ((DataIn_Comp > (TriggerLV >> 3'h2)) && (sigNeg == 1'b0) && (TriggerMode == 2'b10) && (trigGtNeg == 1'b0) && (Trigger_CH == 1'b1) && (TriggerST == 1'b1)) begin
			sigNeg	<= 1'b1;
			cnt2	<= 4'h0;
		end else if ((sigNeg == 1'b1) && (cnt2 < 4'h8)) begin
			cnt2	<= cnt2 + 1'b1;
		end else if (cnt2 == 4'h8) begin
			if (DataIn_Comp < (TriggerLV >> 3'h2)) begin
				trigNeg		<= 1'b1;
				trigGtNeg	<= 1'b1;
				sigNeg		<= 1'b0;
				cnt2		<= 4'h0;
			end else begin
				trigNeg		<= 1'b0;
				sigNeg		<= 1'b0;
				cnt2		<= 4'h0;
			end
		end else begin
			trigNeg	<= trigNeg;
		end
	end
end





endmodule
